package com.example.springboot.service.impl;

import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.springboot.base.Result;
import com.example.springboot.mapper.FolderInfoMapper;
import com.example.springboot.mapper.RootDirectoryInfoMapper;
import com.example.springboot.mapper.UserInfoMapper;
import com.example.springboot.pojo.FolderInfo;
import com.example.springboot.pojo.RootDirectoryInfo;
import com.example.springboot.pojo.UserInfo;
import com.example.springboot.service.UserInfoService;
import com.example.springboot.utils.JWTUtil;
import com.example.springboot.utils.VerCodeGenerateUtil;
import com.example.springboot.utils.hdfs.HdfsUtil;
import com.github.qcloudsms.SmsSingleSender;
import com.github.qcloudsms.SmsSingleSenderResult;
import com.github.qcloudsms.httpclient.HTTPException;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  用户实现类
 * </p>
 *
 * @author 赵久燚
 * @since 2022-07-11 19:45:42
 */
@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

    //验证码缓存，两分钟过期
    Cache<String, String> localCache = CacheBuilder.newBuilder().maximumSize(1000).expireAfterAccess(2, TimeUnit.MINUTES).build();
    @Resource
    private UserInfoMapper userInfoMapper;

    @Resource
    private FolderInfoMapper folderInfoMapper;

    @Resource
    private RootDirectoryInfoMapper rootDirectoryInfoMapper;

    @Override
    public Result userLogin(String username,String password) {
        try{
//            UserInfo user = userInfoMapper.selectOne(new QueryWrapper<UserInfo>()
//                    .select("user_id","user_pwd","user_name")
//                    .eq("user_name", username));
            Map<String, Object> folderMap = userInfoMapper.selectJoinMap(new MPJLambdaWrapper<>()
                    .select(UserInfo::getUserName, UserInfo::getUserPwd)
                    .select(RootDirectoryInfo::getFolderId)
                    .leftJoin(RootDirectoryInfo.class, RootDirectoryInfo::getUserId, UserInfo::getUserId)
                    .eq(UserInfo::getUserName,username));
//            String pwd = user.getUserPwd();
//            String id = user.getUserId();
            if (password.equals(folderMap.get("userPwd"))){
                Map<String, String> map = new HashMap<>();
                map.put("userName", (String) folderMap.get("userName"));
                String token = JWTUtil.getToken(map);
                map.remove("userName");
                map.put("token",token);
                map.put("folderId", (String) folderMap.get("folderId"));
                return Result.success("登录成功", map);
            }
            return Result.error("密码错误");
        } catch (Exception e) {
            return Result.error("用户不存在");
        }
    }

    @Override
    public Result userRegister(String userName, String password, String phoneNumber, String verCode) {
        try {
            //获取缓存中的验证码
            String cacheCaptcha = localCache.getIfPresent(phoneNumber);
            if(cacheCaptcha != null){
                if (cacheCaptcha.equals(verCode.toString())){
                    UserInfo user = new UserInfo();
                    String userId = IdUtil.simpleUUID();
                    user.setUserId(userId);
                    user.setUserName(userName);
                    user.setUserPwd(password);
                    user.setUserTel(phoneNumber);
                    userInfoMapper.insert(user);
                    //删除验证码
                    localCache.invalidate(phoneNumber);
                    String hdfsPath = "/cloud_disk/"+userName;

                    FolderInfo folderInfo = new FolderInfo();
                    String folderId = IdUtil.simpleUUID();
                    folderInfo.setUserId(userId);
                    folderInfo.setFolderId(folderId);
                    folderInfo.setFolderName(userName);
                    folderInfo.setFolderUrl(hdfsPath);
                    folderInfo.setFolderDel(1);
                    folderInfoMapper.insert(folderInfo);


                    RootDirectoryInfo directoryInfo = new RootDirectoryInfo();
                    directoryInfo.setUserId(userId);
                    directoryInfo.setFolderId(folderId);
                    directoryInfo.setRootDirectoryId(IdUtil.fastUUID());
                    rootDirectoryInfoMapper.insert(directoryInfo);

                    HdfsUtil.createFolder(hdfsPath);

                    return Result.success("注册成功");
                }
                return Result.success(201,"验证码错误","");
            }
            return Result.error("未发送验证码");
        }catch (Exception e){
            return Result.error("用户名已经存在");
        }

    }

    public Result token(String token) {
        System.out.println(token);
        String userName = JWTUtil.getValue(token,"userName");
        System.out.println(userName);
        return Result.success(userName);
    }


    // 短信应用 SDK AppID
    @Value("${tx.sms.appid}")
    private Integer appid; // SDK AppID 以1400开头
    // 短信应用 SDK AppKey
    @Value("${tx.sms.appkey}")
    private String appkey;
    // 短信模板 ID，需要在短信应用中申请
    @Value("${tx.sms.templateId}")
    private Integer templateId; // NOTE: 这里的模板 ID`7839`只是示例，真实的模板 ID 需要在短信控制台中申请
    // 签名
    @Value("${tx.sms.smsSign}")
    private String smsSign; // NOTE: 签名参数使用的是`签名内容`，而不是`签名ID`。这里的签名"腾讯云"只是示例，真实的签名需要在短信控制台申请
    @Override
    public Result sendVerCode(String phoneNumber) throws HTTPException, IOException {
        String cacheCaptcha = localCache.getIfPresent(phoneNumber);
//        System.out.println(cacheCaptcha);
        if(cacheCaptcha != null) {return Result.error("请勿重复发送");}
        String ver = VerCodeGenerateUtil.generateVerCode();
        // 这里对应你的短信模板，如果需要传递两个参数，那么字符串数组应该有两个值
        String[] code = new String[]{ver,"2"};
        SmsSingleSender sender = new SmsSingleSender(appid, appkey);
        //发送短信，86 指的是国内短信，第二个是模板的 id，第三个是传递的参数，第四个是签名内容，后面两个可以传递空
        SmsSingleSenderResult result = sender.sendWithParam("86", phoneNumber, templateId,
                code, smsSign, "", "");
        // 如果 result 的结果是 0，说明发送成功
        if (result.result == 0) {
            localCache.put(phoneNumber, ver);
            return Result.success("发送成功");
        } else {// 如果结果不是 0，说明出错了，打印错误信息以帮助修改
            System.out.println(result);
            return Result.error("发送失败",result.errMsg);
        }
    }
}
